// ============================================================================
//
// Copyright (C) 2006-2007 Dengues
//
// Google Group: http://groups.google.com/group/dengues
// QQ Group: 24885404
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
// ============================================================================
package org.dengues.designer.ui.process.models;

import org.dengues.core.metadata.MetadataTable;
import org.dengues.core.process.CompElement;
import org.dengues.core.process.CompProcessHelper;
import org.dengues.core.process.EConnectionType;
import org.dengues.core.process.ICompConnection;
import org.dengues.core.process.ICompProcess;
import org.eclipse.draw2d.geometry.Dimension;
import org.eclipse.draw2d.geometry.Point;

/**
 * Qiang.Zhang.Adolf@gmail.com class global comment. Detailled comment <br/>
 * 
 * @since 2007-9-28 下午10:47:43
 */
public class CompConnection extends CompElement implements ICompConnection {

    private boolean isConnected = false;

    private String name;

    private static final long serialVersionUID = 1323432543L;

    private CompNode source;

    private CompNode target;

    public static String CHANGE = "Change"; //$NON-NLS-1$

    private MetadataTable metadata;

    private CompConnectionLabel connectionLabel;

    private CompConnectionTrac connectionTrac;

    /**
     * Qiang.Zhang.Adolf@gmail.com CompConnection constructor comment.
     */
    public CompConnection(CompNode source, CompNode target, EConnectionType type) {
        this(source, target, type, null);
    }

    public CompConnection(CompNode source, CompNode target, EConnectionType type, String name) {
        if (name == null) {
            this.name = CompProcessHelper.generateNewCompConnectionName(source != null ? source.getCompProcess() : target
                    .getCompProcess(), type.name().toLowerCase());
        } else {
            this.name = name;
        }
        reconnect(source, target);
        init();
    }

    /**
     * Qiang.Zhang.Adolf@gmail.com Comment method "init".
     */
    private void init() {
        connectionLabel = new CompConnectionLabel(this);
        connectionTrac = new CompConnectionTrac(this);
        Point point = new Point();
        point.x = (source.getLocation().x + target.getLocation().x) / 2;
        point.y = (source.getLocation().y + target.getLocation().y) / 2;
        connectionLabel.setLocation(point);
        connectionTrac.setLocation(point.getCopy());
    }

    /**
     * Qiang.Zhang.Adolf@gmail.com Comment method "reconnect".
     * 
     * @param source
     * @param target
     */
    public void reconnect(CompNode newSource, CompNode newTarget) {
        disconnect();
        this.source = newSource;
        this.target = newTarget;
        reconnect();
        fireStructureChange(CHANGE, this);
    }

    /**
     * Qiang.Zhang.Adolf@gmail.com Comment method "reconnect".
     */
    public void reconnect() {
        if (!isConnected) {
            source.addOutgoingConnections(this);
            target.addIncomingConnections(this);
            if (source.getMetadataList().size() == 0) {
                MetadataTable metadataTable = new MetadataTable();
                metadataTable.setTableName(getName());
                setMetadata(metadataTable);
            } else {
                setMetadata(source.getMetadataList().get(0));
            }
            isConnected = true;
            ((CompProcess) getCompProcess()).getConnections().add(this);
        }
    }

    /**
     * Qiang.Zhang.Adolf@gmail.com Comment method "disconnect".
     */
    public void disconnect() {
        if (isConnected) {
            source.removeOutgoingConnections(this);
            target.removeIncomingConnections(this);
            isConnected = false;
            ((CompProcess) getCompProcess()).getConnections().remove(this);
        }
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.dengues.designer.ui.process.models.CompElement#getCompName()
     */
    @Override
    public String getCompName() {
        return this.name;
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.dengues.core.process.ICompConnection#getName()
     */
    public String getName() {
        return this.name;
    }

    /**
     * Sets the name.
     * 
     * @param name the name to set
     */
    public void setName(String name) {
        this.name = name;
    }

    /**
     * Getter for source.
     * 
     * @return the source
     */
    public CompNode getSource() {
        return this.source;
    }

    /**
     * Sets the source.
     * 
     * @param source the source to set
     */
    public void setSource(CompNode source) {
        this.source = source;
        this.source.addOutgoingConnections(this);
    }

    /**
     * Getter for target.
     * 
     * @return the target
     */
    public CompNode getTarget() {
        return this.target;
    }

    /**
     * Sets the target.
     * 
     * @param target the target to set
     */
    public void setTarget(CompNode target) {
        this.target = target;
        this.target.addIncomingConnections(this);
    }

    /**
     * Getter for metadata.
     * 
     * @return the metadata
     */
    public MetadataTable getMetadata() {
        return this.metadata;
    }

    /**
     * Sets the metadata.
     * 
     * @param metadata the metadata to set
     */
    public void setMetadata(MetadataTable metadata) {
        this.metadata = metadata;
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.dengues.core.process.ICompElement#getLocation()
     */
    @Override
    public Point getLocation() {
        return null;
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.dengues.core.process.ICompElement#getSize()
     */
    @Override
    public Dimension getSize() {
        return null;
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.dengues.designer.ui.process.models.CompElement#getCompProcess()
     */
    @Override
    public ICompProcess getCompProcess() {
        if (source != null) {
            return source.getCompProcess();
        }
        if (target != null) {
            return target.getCompProcess();
        }
        return null;
    }

    /**
     * Getter for connectionLabel.
     * 
     * @return the connectionLabel
     */
    public CompConnectionLabel getConnectionLabel() {
        return this.connectionLabel;
    }

    public CompConnectionTrac getConnectionTrac() {
        return this.connectionTrac;
    }

}
